package org.itboys.shop.service.Manager;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.itboys.basetemplate.entity.VoucherUserMap;
import org.itboys.basetemplate.service.VoucherUserMapService;
import org.itboys.commons.CommonConstants.DF;
import org.itboys.commons.CommonConstants.NUM;
import org.itboys.commons.CommonConstants.StaticParam;
import org.itboys.commons.utils.number.C;
import org.itboys.commons.utils.random.RandomUtils;
import org.itboys.commons.utils.string.SelfStringUtils;
import org.itboys.commons.utils.time.DateUtils;
import org.itboys.commons.utils.tools.ImagePathUtils;
import org.itboys.member.entity.Member;
import org.itboys.member.entity.MemberInfo;
import org.itboys.member.service.MemberInfoService;
import org.itboys.product.entity.CommonTouristInfo;
import org.itboys.product.entity.Product;
import org.itboys.product.entity.ProductSpecDetail;
import org.itboys.product.entity.ReceiveAddress;
import org.itboys.product.service.CommonTouristInfoService;
import org.itboys.product.service.GoodsSourcePostFeeService;
import org.itboys.product.service.GoodsSourceService;
import org.itboys.product.service.ProductService;
import org.itboys.product.service.ProductSpecDetailService;
import org.itboys.product.service.ReceiveAddressService;
import org.itboys.shop.dto.order.WXOrderDetailDto;
import org.itboys.shop.dto.order.WXOrderItemDto;
import org.itboys.shop.dto.order.WXOrderListDto;
import org.itboys.shop.dto.order.WXPreOrderDto_jd;
import org.itboys.shop.dto.order.WXPreOrderDto_ms;
import org.itboys.shop.dto.order.WXPreOrderDto_njl;
import org.itboys.shop.dto.order.WXTicketOrderDetailDto;
import org.itboys.shop.dto.order.WXTicketOrderItemDto;
import org.itboys.shop.dto.order.WXTicketOrderListDto;
import org.itboys.shop.dto.order.WXToPayDto;
import org.itboys.shop.service.ShopSellerService;
import org.itboys.shop.tools.ShipDic;
import org.itboys.shop.tools.UUIDUtils;
import org.itboys.trade.constant.OrderConstant;
import org.itboys.trade.entity.Cart;
import org.itboys.trade.entity.Order;
import org.itboys.trade.entity.OrderItem;
import org.itboys.trade.entity.TicketOrder;
import org.itboys.trade.entity.TicketOrderItem;
import org.itboys.trade.service.OrderItemService;
import org.itboys.trade.service.OrderService;
import org.itboys.trade.service.TicketOrderItemService;
import org.itboys.trade.service.TicketOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class WXOrderManager {
	@Autowired
	private OrderService orderService;
	@Autowired
	private OrderItemService itemService;
	@Autowired
	private ProductService proService;
	@Autowired
	private GoodsSourceService sourceService;
	@Autowired
	private WXProManager proManager;
	@Autowired
	private ProductSpecDetailService specService;
	@Autowired
	private VoucherUserMapService voucherService;
	@Autowired
	private TicketOrderService ticketOrderService;
	@Autowired
	private TicketOrderItemService ticketOrderItemService;
	@Autowired
	private ShopSellerService sellerService;
	@Autowired
	 private CommonTouristInfoService infoService;
	@Autowired
    private ReceiveAddressService receiveAddressService;
	@Autowired
	private GoodsSourcePostFeeService postFeeService;
	private List<WXOrderItemDto>getItemDtos(Long orderId){
		return itemService.findByField("orderId", orderId).stream().map(i->{
			WXOrderItemDto dto=new WXOrderItemDto();
			dto.setImage(ImagePathUtils.add(StaticParam.imagePath, i.getProductImg()));
			dto.setItemId(i.getId());
			dto.setLocation(i.getLocation());
			dto.setName(i.getProductName());
			dto.setNum(i.getNum());
			dto.setPrice(NUM.DF_00.format(i.getNowPrice()/100d));
			dto.setElements(i.getElements());
			return dto;
		}).collect(Collectors.toList());
	}
	
	public WXOrderListDto getListDto(Order order){
		return getListDto(order, null);
	}
	public WXOrderListDto getListDto(Order order,WXOrderListDto dto){
		if (null==dto) {
			dto=new WXOrderListDto();
		}
		dto.setOrderId(order.getId());
		dto.setExpressName(ShipDic.getCode(order.getExpress()));
		dto.setExpressNo(order.getExpressNo());
		dto.setItems(getItemDtos(order.getId()));
		dto.setOrderNo(order.getOrderNo());
		dto.setStatus(order.getStatus());
		dto.setNum(dto.getItems().stream().mapToInt(i->i.getNum()).sum());
		dto.setTotalFee(NUM.DF_00.format(order.getTotalMoney()/100d));
		return dto;
	}
	public WXOrderDetailDto getDetailDto(Order order){
		WXOrderDetailDto dto=(WXOrderDetailDto)getListDto(order, new WXOrderDetailDto());
		dto.setExpressFee(NUM.DF_00.format(order.getExpressFee()/100d));
		dto.setCreateTime(DF.FORMAT_DEFAULT.format(order.getCt()));
		dto.setToName(order.getName());
		dto.setToAddress(order.getAddress());
		dto.setToPhone(order.getMobile());
		dto.setAddressId(order.getAddressId());
		return dto;
	}
	private List<WXTicketOrderItemDto>getTicketItemDto(Long orderId){
		return ticketOrderItemService.findByField("orderId", orderId).stream().map(i->{
			WXTicketOrderItemDto dto=new WXTicketOrderItemDto();
			dto.setItemId(i.getId());
			dto.setName(i.getProductName());
			dto.setNum(i.getNum());
			dto.setPrice(NUM.DF_00.format(i.getNowPrice()/100d));
			dto.setDays(i.getDays());
			dto.setEnd(null==i.getEnd()?"":DF.FORMAT_YYYY_MM_dd.format(i.getEnd()));
			dto.setStart(DF.FORMAT_YYYY_MM_dd.format(i.getStart()));
			return dto;
		}).collect(Collectors.toList());
	}
	
	public WXTicketOrderListDto getTicketListDto(TicketOrder order){
		return getTicketListDto(order, null);
	}
	public WXTicketOrderListDto getTicketListDto(TicketOrder order,WXTicketOrderListDto dto){
		if (null==dto) {
			dto=new WXTicketOrderListDto();
		}
		dto.setOrderId(order.getId());
		dto.setItems(getTicketItemDto(order.getId()));
		dto.setOrderNo(order.getOrderNo());
		dto.setStatus(order.getStatus());
		dto.setTotalFee(NUM.DF_00.format(order.getTotalMoney()/100d));
		dto.setSellerName(order.getSellerName());
		
		return dto;
	}
	public WXTicketOrderDetailDto getTicketDetailDto(TicketOrder order){
		WXTicketOrderDetailDto dto=(WXTicketOrderDetailDto)getTicketListDto(order, new WXTicketOrderDetailDto());
		dto.setVoucherUserMap(new VoucherUserMap());
		dto.setPoints(0);
		dto.setTicketAddress(dto.getSellerName());
		dto.setTicketDelivery("上门自取");
		dto.setPayType(0);
		dto.setCode(order.getCode());
		dto.setCreateTime(DF.FORMAT_DEFAULT.format(order.getCt()));
		return dto;
	}
	public WXToPayDto getPreItemDto(List<WXOrderItemDto> items, Cart c,Long cityId) {
		WXOrderItemDto dto=new WXOrderItemDto();
		Product pro=proService.getById(c.getProductId());
		dto.setImage(ImagePathUtils.add(StaticParam.imagePath, pro.getImage()));
		dto.setLocation(sourceService.getSourceCityName(pro.getSource()));
		dto.setName(pro.getName());
		dto.setNum(c.getNum());
		dto.setPrice(NUM.DF_00.format(c.getPrice()/100d));
		dto.setElements(proManager.getSpecName(c.getSpecDetailId()));
		items.add(dto);
		WXToPayDto payDto=new WXToPayDto();
		payDto.setTotalFee(c.getPrice()*dto.getNum());
		payDto.setExpressFee(postFeeService.getExpressFee(pro.getWeigth()*c.getNum(), pro.getSource(), cityId));
		return payDto;
	}
	public Order createOrder(ReceiveAddress address,Long memberId){
		Order order=new Order();
		order.setAddress(address.getAddress());
		order.setAddressId(address.getId());
		order.setName(address.getName());
		order.setMobile(SelfStringUtils.mixMobile(address.getMobile()));
		order.setExpressFee(0);
		order.setOrderNo("WO"+DF.FORMAT_yyyyMMddHHmmss.format(new Date())+RandomUtils.buildRandom(4));
		order.setMemberId(memberId);
		order.setStatus(OrderConstant.WAIT_PAY);
		orderService.save(order);
		return order; 
	}
	public TicketOrder createTicketOrder(Integer type,Member member){
		TicketOrder order=new TicketOrder();
		String head=null;
		switch (type) {
		case 2:
			head="M";
			break;
		case 5:
			head="N";
			break;
		case 4:
			head="J";
			break;
		default:
			break;
		}
		order.setOrderNo(head+DF.FORMAT_yyyyMMddHHmmss.format(new Date())+RandomUtils.buildRandom(4));
		order.setMemberId(member.getId());
		order.setCenterId(member.getCenterId());
		order.setCode(UUIDUtils.id(12).toLowerCase());
		ticketOrderService.save(order);
		return order;
	}
	public WXToPayDto createItems(Cart c,Long orderId,Long cityId){
		OrderItem item=new OrderItem();
		Product pro=proService.getById(c.getProductId());
		item.setElements(proManager.getSpecName(c.getSpecDetailId()));
		item.setLocation(sourceService.getSourceCityName(pro.getSource()));
		item.setMemberId(c.getMemberId());
		item.setPrice(pro.getProPrice());
		item.setNowPrice(c.getPrice());
		item.setTotalFee(c.getFee());
		item.setNum(c.getNum());
		item.setProductId(c.getProductId());
		item.setProductImg(pro.getImage());
		item.setProductName(pro.getName());
		item.setOrderId(orderId);
		item.setScale(pro.getIsDistributed()==2?pro.getScale():0);
		itemService.save(item);
		WXToPayDto dto=new WXToPayDto();
		dto.setTotalFee(item.getTotalFee());
		dto.setExpressFee(postFeeService.getExpressFee(pro.getWeigth()*c.getNum(), pro.getSource(), cityId));
		dto.setScale(item.getScale()*item.getNum());
		return dto;
	}
	public WXToPayDto createTicketItem(Long proId,Long memberId,Long orderId,int num,String start,String end) throws ParseException{
		TicketOrderItem item=new TicketOrderItem();
		Product pro=proService.getById(proId);
		List<ProductSpecDetail>specs=specService.getByProduct(proId);
		ProductSpecDetail spec=specs.size()>0?specs.get(0):null;
		item.setElements(proManager.getSpecName(spec));
		item.setMemberId(memberId);
		item.setPrice(pro.getProPrice());
		item.setNowPrice(pro.getPrice());
		Date s=DF.FORMAT_YYYY_MM_dd.parse(start);
		if (null!=end) {
			Date e=DF.FORMAT_YYYY_MM_dd.parse(end);
			int days=DateUtils.daysBetween(s, e);
			item.setDays(days);
			item.setEnd(e.getTime());
			item.setTotalFee((int)C.multiply(days,num,item.getNowPrice()));
		}else {
			item.setTotalFee((int)C.multiply(num,item.getNowPrice()));
		}
		item.setStart(s.getTime());
		item.setNum(num);
		item.setProductId(proId);
		item.setProductImg(pro.getImage());
		item.setProductName(pro.getName());
		item.setOrderId(orderId);
		item.setScale(pro.getIsDistributed()==2?pro.getScale():0);
		ticketOrderItemService.save(item);
		WXToPayDto dto=new WXToPayDto();
		dto.setTotalFee(item.getTotalFee());
		dto.setScale(item.getScale()*item.getNum());
		dto.setSellerId(pro.getSellerId());
		dto.setSellerName(sellerService.getById(pro.getSellerId()).getShopName());
		return dto;
	}
	public WXPreOrderDto_ms getPreOrder_ms(	Long proId,
			List<Long>infoIds,
			 String start,
			 String end,
			 Integer num,
			 Long ticketId,
			 Integer points
			) throws ParseException{
		Product product=proService.getById(proId);
		List<ProductSpecDetail>specs=specService.getByProduct(proId);
		ProductSpecDetail spec=specs.size()>0?specs.get(0):null;
		WXPreOrderDto_ms dto=new WXPreOrderDto_ms();
		dto.setProId(proId);
		dto.setTicketId(ticketId);
		dto.setElements(proManager.getSpecName(spec));
		dto.setStart(StringUtils.isBlank(start)?DF.FORMAT_YYYY_MM_dd.format(new Date()):start);
		dto.setEnd(StringUtils.isBlank(end)?DF.FORMAT_YYYY_MM_dd.format(DateUtils.addDay(DF.FORMAT_YYYY_MM_dd.parse(dto.getStart()),1)):end);
		infoIds.remove(null);
		dto.setMemberInfoIds(infoIds);
		//		if (infoIds.size()>0) {
//			dto.setGuests(new ArrayList<>());
//			List<CommonTouristInfo>list=infoService.getByIds(infoIds);
//			dto.setGuests(
//					list.stream().map(i->{
//						MemberInfo info=new MemberInfo();
//						info.setName(i.getName());
//						info.setType(MemberInfo.type_id);
//						info.setGuestType(MemberInfo.guest_type_adult);
//						info.setMobile(SelfStringUtils.mixMobile(i.getMobile()));
//						return info;
//					}).collect(Collectors.toList())
//			);
//		}
		dto.setDays(DateUtils.daysBetween(dto.getStart(), dto.getEnd()));
		dto.setNum(null==num?1:num);
		dto.setPoints(0);
		dto.setPrice(NUM.DF_00.format(product.getPrice()/100));
		dto.setRoomName(product.getName());
		dto.setTotal(NUM.DF_00.format((Integer)C.multiply(product.getPrice()/100,dto.getNum(),dto.getDays())));
		return dto;
	}
	public WXPreOrderDto_njl getPreOrder_njl(	Long proId,
			List<Long>infoIds,
			 String start,
			 Integer num,
			 Long ticketId,
			 Integer points
			) throws ParseException{
		Product product=proService.getById(proId);
		WXPreOrderDto_njl dto=new WXPreOrderDto_njl();
		dto.setProId(proId);
		infoIds.remove(null);
		dto.setMemberInfoIds(infoIds);
		dto.setTicketId(ticketId);
		dto.setStart(StringUtils.isBlank(start)?DF.FORMAT_YYYY_MM_dd.format(new Date()):start);
//		if (infoIds.size()>0) {
//			dto.setGuests(new ArrayList<>());
//			List<CommonTouristInfo>list=infoService.getByIds(infoIds);
//			dto.setGuests(
//					list.stream().map(i->{
//						MemberInfo info=new MemberInfo();
//						info.setName(i.getName());
//						info.setType(MemberInfo.type_id);
//						info.setGuestType(MemberInfo.guest_type_adult);
//						info.setMobile(SelfStringUtils.mixMobile(i.getMobile()));
//						return info;
//					}).collect(Collectors.toList())
//			);
//		}
		dto.setNum(null==num?1:num);
		dto.setPoints(0);
		dto.setPrice(NUM.DF_00.format(product.getPrice()/100));
		dto.setName(product.getName());
		dto.setTotal(NUM.DF_00.format((Integer)C.multiply(product.getPrice()/100,dto.getNum())));
		return dto;
	}
	public WXPreOrderDto_jd getPreOrder_jd(Double ensureAmount,	Long proId,
			List<Long>infoIds,
			 String start,
			 Integer num,
			 Long ticketId,
			 Integer points
			) throws ParseException{
		Product product=proService.getById(proId);
		WXPreOrderDto_jd dto=new WXPreOrderDto_jd();
		dto.setProId(proId);
		dto.setMemberInfoIds(infoIds);
		dto.setTicketId(ticketId);
		dto.setStart(StringUtils.isBlank(start)?DF.FORMAT_YYYY_MM_dd.format(new Date()):start);
//		if (infoIds.size()>0) {
//			dto.setGuests(new ArrayList<>());
//			List<CommonTouristInfo>list=infoService.getByIds(infoIds);
//			dto.setGuests(
//					list.stream().map(i->{
//						MemberInfo info=new MemberInfo();
//						info.setName(i.getName());
//						info.setType(MemberInfo.type_id);
//						info.setGuestType(MemberInfo.guest_type_adult);
//						info.setMobile(SelfStringUtils.mixMobile(i.getMobile()));
//						return info;
//					}).collect(Collectors.toList())
//			);
//		}
		dto.setNum(null==num?1:num);
		dto.setPoints(0);
		dto.setPrice(NUM.DF_00.format(product.getPrice()/100));
		dto.setName(product.getName());
		dto.setTotal(NUM.DF_00.format((Integer)C.multiply(product.getPrice()/100,dto.getNum())+ensureAmount));
		return dto;
	}
}
